第一個
http://127.0.0.1:8000/storage/images/2CeP1jTIXxIAywLQkfWektiezeDuQhUlunqb6VZX.jpg
第2個
http://127.0.0.1:8000/storage/images/gGzw2Y0y9fyype8tu0KXKrbjsDN9llWLz1hu6px8.png
後端看
相關的程式碼
程式碼
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Models\Product;
use App\Http\Controllers\Controller;
use App\Notifications\ProductDelivery;
class ProductController extends Controller
{
public function index(Request $request)
{
$productCount = Product::count();
$dataPerPage = 2;
$productPages = ceil($productCount / $dataPerPage);
$currentPage = isset($request->all()['page']) ? $request->all()['page'] : 1;
$products = Product::orderBy('created_at','desc')
->offset($dataPerPage * ($currentPage - 1))
->limit($dataPerPage)
->get();
return view('admin.products.index',['products' => $products,
'productCount' => $productCount,
'productPages' => $productPages]);
}
public function uploadImage(Request $request)
{
$request->validate([
'product_id' => 'required|integer|exists:products,id',
'product_image' => 'required|image|max:2048',
]);
$product = Product::findOrFail($request->product_id);
$path = $request->file('product_image')->store('images', 'public');
$filename = basename($path);
// Create a new image record in the images table instead of updating products table
$product->images()->create([
'path' => $path,
'filename' => $filename,
'attachable_type' => 'App\Models\Product',
//'attachable_type' => Product::class, // Use ::class instead of string literal
'attachable_id' => $product->id,
]);
return redirect()->back()->with('success', '圖片上傳成功');
}
}
程式碼
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
protected $guarded = [];
public function attachable()
{
return $this->morphTo();
}
}
程式碼
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Product extends Model
{
use HasFactory;
protected $guarded =[''];
public function cartItems()
{
return $this->hasMany(CartItem::class);
}
public function orderItems()
{
return $this->hasMany(OrderItem::class);
}
public function checkQuantity($quantity)
{
if ($this->quantity < $quantity) {
return false;
}
return true;
}
public function images()
{
return $this->morphMany(Image::class, 'attachable');
}
public function getImageUrlAttribute()
{
$images = $this->images;
if ($images->isNotEmpty()){
return Storage::url($images->last()-path);
}
}
}
程式碼
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateImages extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('attachable_type', 255)->comment('來源表');
$table->string('attachable_id', 255)->comment('來源表ID');
$table->string('path', 255)->comment('路徑');
$table->string('filename', 255)->comment('檔案名稱');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('images');
}
}
程式碼
@extends('layouts.admin_app')
@section('content')
<h2>產品列表</h2>
<span>產品總數: {{ $productCount }} </span>
<table>
<thead>
<tr>
<td>編號</td>
<td>標題</td>
<td>內容</td>
<td>價格</td>
<td>數量</td>
<td>圖片</td>
<td>功能</td>
</tr>
</thead>
<tbody>
@foreach( $products as $product )
<tr>
<td>{{ $product->id }}</td>
<td>{{ $product->title }}</td>
<td>{{ $product->content }}</td>
<td>{{ $product->price }}</td>
<td>{{ $product->quantity }}</td>
<td>
@if($product->images->isNotEmpty())
<a href="{{ asset('storage/' . $product->images->first()->path) }}">圖片連結</a>
@else
無圖片
@endif
</td>
<td>
<input type="button" class="upload_image" data-id="{{ $product->id }}" value="上傳圖片">
</td>
</tr>
@endforeach
</tbody>
</table>
<div>
@for ($i = 1; $i <= $productPages; $i++)
<a href="/admin/products?page={{ $i }}">第 {{ $i }} 頁</a>
@endfor
</div>
<!-- Add Modal for Image Upload -->
<div class="modal fade" id="upload_image_modal" tabindex="-1" role="dialog" aria-labelledby="uploadImageModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="uploadImageModalLabel">上傳圖片</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- <form id="upload_form" method="POST" enctype="multipart/form-data">-->
<form id="upload_form" method="POST" action="/admin/products/upload-image" enctype="multipart/form-data">
@csrf
<input type="hidden" id="product_id" name="product_id">
<div class="form-group">
<label for="product_image">選擇圖片</label>
<input type="file" class="form-control" id="product_image" name="product_image">
</div>
<button type="submit" class="btn btn-primary">上傳</button>
</form>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('.upload_image').click(function() {
$('#product_id').val($(this).data('id'));
$('#upload_image_modal').modal('show');
});
});
</script>
@endsection
程式碼
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
//Route::get('/', function () {
//return view('welcome');
//return view('index');
//});
Route::get('/', 'WebController@index');
Route::get('/contact-us', 'WebController@contactUs');
Route::post('/read-notification', 'WebController@readNotification');
Route::post('/products/check-product', 'ProductController@checkProduct');
Route::resource('products', 'ProductController');
Route::resource('admin/orders', 'Admin\OrderController');
Route::resource('admin/products', 'Admin\ProductController');
Route::post('admin/products/upload-image', 'Admin\ProductController@uploadImage');
Route::post('admin/orders/{id}/delivery', 'Admin\OrderController@delivery');
Route::post('signup','AuthController@signup');
Route::post('login','AuthController@login');
Route::group([
'middleware' => 'auth:api'
],
function () {
Route::get('user', 'AuthController@user');
Route::get('logout', 'AuthController@logout');
Route::post('carts/checkout', 'CartController@checkout');
Route::resource('carts', 'CartController');
Route::resource('cart-items', 'CartItemController');
}
);
程式碼
<!-- Modal -->
<div class="modal fade" id="upload_image_modal" tabindex="-1" role="dialog" aria-labelledby="uploadImageModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="uploadImageModalLabel">上傳圖片</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="upload_form" method="POST" action="/admin/products/upload-image" enctype="multipart/form-data">
@csrf
<input type="hidden" id="product_id" name="product_id">
<div class="form-group">
<label for="product_image">選擇圖片</label>
<input type="file" class="form-control" id="product_image" name="product_image">
</div>
<button type="submit" class="btn btn-primary">上傳</button>
</form>
</div>
</div>
</div>
</div>
程式碼 更新後要啟動
php artisan serve
畫面上傳圖片後
資料表會lag 要重新整理
大家明天見~